package com.ruoyi.web.controller.xxc;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.WxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.utils.wxUtils.SendWxMapMsg;
import com.ruoyi.common.utils.wxUtils.TemplateData;
import com.ruoyi.common.utils.wxUtils.Wxmp;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.news.domain.ResUser;
import com.ruoyi.news.domain.WxRegisterBody;
import com.ruoyi.news.domain.XxcWallet;
import com.ruoyi.news.service.IXxcWalletService;
import com.ruoyi.news.service.WxMpSysUserService;
import com.ruoyi.news.utils.WxRedisAccessToken;
import com.ruoyi.system.service.ISysUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.ruoyi.news.domain.WxLoginBody;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;


@Api(value = "wxuser-longin", tags = {"微信小程序"})
@RestController
@RequestMapping("/WxOpenApi")
public class LoginController extends BaseController {


    @Autowired
    private SysLoginService loginService;

    @Autowired
    ISysUserService userService;

    @Autowired
    public RedisCache redisCache;

    @Autowired
    public WxMpSysUserService wxMpSysUserService;

    @Autowired
    public IXxcWalletService xxcWalletService;

    /** 用户微信小程序登录 */
    @ApiOperation(value = "用户微信小程序登录")
    @PostMapping("/userPassword")
    @Log(title = "用户微信小程序登录",businessType = BusinessType.OTHER)
    public WxResult userPassword(@RequestBody WxLoginBody body) {
        Map<String,Object> namePasswordMap = wxMpSysUserService.getUserNamePassword(body);

        if(body != null){
            if(!body.getUserName().isEmpty() && !body.getPassword().isEmpty()){
                try {
                    HashMap hm = loginService.login(body.getUserName(),body.getPassword() );
                    return new WxResult(HttpStatus.SUCCESS, "登录成功", hm);
                } catch (Exception e){
                    return new WxResult(HttpStatus.ERROR, "登录失败,用户信息错误！");
                }
            }else{
                Map<String,Object> resultMap = new HashMap<>();
                resultMap.put("code",HttpStatus.ERROR);
                resultMap.put("msg","登录失败,用户未注册!");
                resultMap.put("appletOpenId",body.getAppletOpenId());
                return new WxResult(HttpStatus.SUCCESS, "登录失败",resultMap);
            }
        }else{
            return new WxResult(HttpStatus.ERROR, "登录失败,未提供登录信息!");
        }
    }


    /** 用户微信小程序登录 */
    @ApiOperation(value = "用户微信小程序登录")
    @PostMapping("/appletLogin")
    @Log(title = "用户微信小程序登录",businessType = BusinessType.OTHER)
    public WxResult appletLogin(@RequestBody WxLoginBody body) {
        if(body != null){
            Map<String,Object> namePasswordMap = wxMpSysUserService.getUserNamePassword(body);
            if(namePasswordMap != null && !namePasswordMap.isEmpty()){
                try {
                    HashMap hm = loginService.login((Long)namePasswordMap.get("userId"), (Long)namePasswordMap.get("deptId"),(SysUser) namePasswordMap.get("sysUser"));
                    return new WxResult(HttpStatus.SUCCESS, "登录成功", hm);
                } catch (Exception e){
                    return new WxResult(HttpStatus.ERROR, "登录失败,用户信息错误！");
                }
            }else{
                Map<String,Object> resultMap = new HashMap<>();
                resultMap.put("code",HttpStatus.ERROR);
                resultMap.put("msg","登录失败,用户未注册!");
                resultMap.put("appletOpenId",body.getAppletOpenId());
                return new WxResult(HttpStatus.SUCCESS, "登录失败",resultMap);
            }
        }else{
            return new WxResult(HttpStatus.ERROR, "登录失败,未提供登录信息!");
        }
    }

    /**
     * 微信小程序找回密码 用验证码
     */
    @GetMapping(value = "/findPswIncode")
    public WxResult findPswIncode(WxRegisterBody body) {
        //检验redis存的用户验证短信是否过期
        Object reCode = redisCache.getCacheObject(body.getUsername());
        if (reCode != null) {
            if ( body.getYzCode() != null && reCode.toString().equals(body.getYzCode())) {
                String passtr = userService.getPassword(body.getUsername(), body.getUsername());
                String passwordNew = body.getPasswordnew();
                if (SecurityUtils.matchesPassword(passwordNew, passtr)) {
                    return new WxResult(HttpStatus.ERROR, "新密码不能与旧密码相同");
                }
                userService.resetUserPwd(body.getUsername(), SecurityUtils.encryptPassword(body.getPasswordnew()));
                return new WxResult(HttpStatus.SUCCESS, "修改密码成功");
            } else {
                return new WxResult(HttpStatus.ERROR, "验证码错误，请重新获取验证码！");
            }
        } else {
            return new WxResult(HttpStatus.ERROR, "验证码超时，请重新获取验证码！");
        }
    }


    /**
     * 忘记密码
     * @return
     */
    @PostMapping("/appfgassword")
    @ApiOperation(value = "忘记密码")
    public WxResult appfgassword(@RequestBody WxRegisterBody body) {
        //获取密码字符
        String passtr = userService.getPassword(body.getUsername(), body.getUsername());

        String passwordNew = body.getPasswordnew();
        if (SecurityUtils.matchesPassword(passwordNew, passtr)) {
            return new WxResult(HttpStatus.ERROR, "新密码不能与旧密码相同");
        }
        int count = userService.resetUserPwd(body.getUsername(), SecurityUtils.encryptPassword(passwordNew));
        if (count > 0) {
            return new WxResult(HttpStatus.SUCCESS, "修改密码成功！");
        } else {
            return new WxResult(HttpStatus.ERROR, "修改密码失败，请联系管理员修改！");
        }
    }


    /**
     * 修改密码
     * @return
     */
    @PostMapping("/appUpassword")
    @ApiOperation(value = "修改密码")
    public WxResult appUpassword(@RequestBody WxRegisterBody body) {
        //获取密码字符
        String passtr = userService.getPassword(body.getUsername(), body.getPhone());
        if (StringUtils.isBlank(passtr)) {
            return new WxResult(HttpStatus.ERROR, "用户名或手机号输入有误，请重新输入！");
        }
        String passwordOld = body.getPassword();
        String passwordNew = body.getPasswordnew();
        if (!SecurityUtils.matchesPassword(passwordOld, passtr)) {
            return new WxResult(HttpStatus.ERROR, "修改密码失败，旧密码错误");
        }
        if (SecurityUtils.matchesPassword(passwordNew, passtr)) {
            return new WxResult(HttpStatus.ERROR, "新密码不能与旧密码相同");
        }
        int count = userService.resetUserPwd(body.getUsername(), SecurityUtils.encryptPassword(passwordNew));
        if (count > 0) {
            return new WxResult(HttpStatus.SUCCESS, "修改密码成功！");
        } else {
            return new WxResult(HttpStatus.ERROR, "修改密码失败，请联系管理员修改！");
        }
    }

    @GetMapping("/getCode")
    @Log(title = "企业注册",businessType = BusinessType.OTHER)
    public WxResult getCode(String jsCode,String phoneNum) {

        if(redisCache.hasKey(phoneNum)) { //存在
            return new WxResult(HttpStatus.ERROR, "5分钟内禁止重复发送!");

        }else{ //不存在
            Random random = new Random();
            int randomNumber = 1000 + random.nextInt(9000); // 生成1000到9000之间的随机数
            SendSmsUtil.sendSMS(phoneNum, randomNumber + "");
            redisCache.setCacheObject(phoneNum, randomNumber, 5, TimeUnit.MINUTES);
            return new WxResult(HttpStatus.SUCCESS, "发送成功,验证码有效期为5分钟!");        }

    }


    /**
     * 企业端注册
     * @return
     */
    @ApiOperation(value = "企业注册")
    @PostMapping("/wxRegister")
    public WxResult wxRegister(@RequestBody @Valid WxRegisterBody body) throws WxErrorException {
        SysUser sysUser =  userService.selectUserByUserName(body.getUsername());
        if(sysUser != null){
            return new WxResult(HttpStatus.ERROR, "用户名已存在,请选择修改登录并修改密码！");
        }
        if(redisCache.hasKey(body.getUsername())) {// 存在
            String yzCode = redisCache.getCacheObject(body.getUsername()).toString();
            if(yzCode.equals(body.getYzCode())){// 验证码 是否一致
                JSONObject obj = wxMpSysUserService.wxGetOpenId(body.getJsCode());
                //用户信息
                SysUser user = new SysUser();
                String name = body.getUsername().substring(body.getUsername().length() -4);
                user.setNickName("用户"+name);
                user.setUserName(body.getUsername());
                user.setPhonenumber(body.getUsername());
                user.setCreateBy(body.getUsername());
                user.setUpdateBy(body.getUsername());
                user.setCreateTime(DateUtils.getNowDate());
                user.setUpdateTime(DateUtils.getNowDate());
                user.setPassword(SecurityUtils.encryptPassword(body.getPassword()));
                user.setOpenId(obj.get("openid").toString());
                user.setDeptId(999999L);
                Random random = new Random();
                int num = random.nextInt(9000000)+10000000;
                user.setNewUserId( num+"" );
                //默认状态： 0正常
                user.setStatus("0");
                //默认状态： 0未审核
                user.setRoleState("0");
                int count = userService.insertUser(user);
                if (count > 0) {
                    XxcWallet xxcWallet = new XxcWallet();
                    xxcWallet.setId(IdUtils.fastSimpleUUID());
                    xxcWallet.setYuE(new BigDecimal(0.00));
                    xxcWallet.setUserId(user.getUserId().toString());
                    xxcWallet.setAccount(user.getPhonenumber());

                    xxcWalletService.insertXxcWallet(xxcWallet);

                    HashMap hm = loginService.login(body.getUsername(),body.getPassword() );
                    return new WxResult(HttpStatus.SUCCESS, "注册成功",hm);
                } else {
                    return new WxResult(HttpStatus.ERROR, "注册失败！");
                }
            }else{
                return new WxResult(HttpStatus.ERROR, "验证码输入错误！");
            }

        }else{ //不存在
            return new WxResult(HttpStatus.ERROR, "验证码已过期！");
        }
    }

    /**
     * 小程序用户获取openid
     * @return
     */
    @ApiOperation(value = "小程序用户登录")
    @GetMapping("/wxGetOpenId")
    public AjaxResult wxGetOpenId(String jsCode){
        try {
            if(!StringUtils.isNotBlank(jsCode)){
                return AjaxResult.error("jsCode不能为空");
            }
            JSONObject obj = wxMpSysUserService.wxGetOpenId(jsCode);
            return AjaxResult.success(obj);
        } catch (Exception e) {
            return AjaxResult.error("微信OpenId获取有误！");
        }
    }

    @GetMapping("/getUserByIdOrName")
    public AjaxResult getUserByIdOrName(SysUser sysUser){
        try {
            SysUser obj = userService.selectUserById(sysUser.getUserId());
            ResUser user = new ResUser();
            user.setValue(obj.getUserId());
            user.setLabel(obj.getNickName());
            return AjaxResult.success(user);
        } catch (Exception e) {
            return AjaxResult.error("微信OpenId获取有误！");
        }
    }

    @Autowired
    private WxRedisAccessToken wxRedisAccessToken;

    @GetMapping("/getAccessToken")
    public AjaxResult getUserByIdOrName(){
        return AjaxResult.success(wxRedisAccessToken.getWxAccessToken());
    }



}